import { AxiosResponse, AxiosRequestConfig } from 'axios';
import { Configuration } from '/@/api-services/configuration';
import { BASE_PATH, RequestArgs, BaseAPI } from '/@/api-services/base';
import { AdminResultListSysFile, AdminResultSqlSugarPagedListSysFile, AdminResultSysFile, SysFile, AdminResultIActionResult, PageFileInput } from '/@/api-services/models';

/**
 * SysFile API Service
 * Provides methods for managing system files including upload, download, and metadata operations
 */
export class FileApi extends BaseAPI {
	constructor(configuration?: Configuration, basePath?: string) {
		super(configuration, basePath);
	}

	/**
	 * Upload a file with metadata
	 */
	async uploadFile(
		file: Blob,
		path: string = 'files',
		metadata?: {
			savePath?: string;
			allowSuffix?: string;
			fileType?: string;
			appSource?: string;
			category?: string;
			relationName?: string;
			relationId?: number;
			belongId?: number;
		}
	): Promise<AxiosResponse<AdminResultSysFile>> {
		const formData = new FormData();
		formData.append('File', file);
		formData.append('Path', path);

		// Add optional metadata if provided
		if (metadata?.savePath) formData.append('SavePath', metadata.savePath);
		if (metadata?.allowSuffix) formData.append('AllowSuffix', metadata.allowSuffix);
		if (metadata?.fileType) formData.append('FileType', metadata.fileType);
		if (metadata?.appSource) formData.append('AppSource', metadata.appSource);
		if (metadata?.category) formData.append('Category', metadata.category);
		if (metadata?.relationName) formData.append('RelationName', metadata.relationName);
		if (metadata?.relationId) formData.append('RelationId', metadata.relationId.toString());
		if (metadata?.belongId) formData.append('BelongId', metadata.belongId.toString());

		const headers: Record<string, string> = {
			'Content-Type': 'multipart/form-data',
		};

		if (this.configuration?.accessToken) {
			const token = typeof this.configuration.accessToken === 'function' ? await this.configuration.accessToken() : await this.configuration.accessToken;
			headers['Authorization'] = `Bearer ${token}`;
		}

		const requestConfig: AxiosRequestConfig = {
			method: 'POST',
			url: this.basePath + '/api/sysFile/uploadFile',
			headers,
			data: formData,
			responseType: 'json',
		};

		return this.axios.request<AdminResultSysFile>(requestConfig);
	}

	/**
	 * Get paginated list of files
	 */
	async getFileList(params: PageFileInput): Promise<AxiosResponse<AdminResultSqlSugarPagedListSysFile>> {
		const headers = await this.getHeaders('application/json');

		const requestConfig: AxiosRequestConfig = {
			method: 'POST',
			url: this.basePath + '/api/sysFile/page',
			headers,
			data: params,
			responseType: 'json',
		};

		return this.axios.request<AdminResultSqlSugarPagedListSysFile>(requestConfig);
	}

	/**
	 * Delete a file by ID
	 */
	async deleteFile(id: number): Promise<AxiosResponse<void>> {
		const headers = await this.getHeaders('application/json');

		const requestConfig: AxiosRequestConfig = {
			method: 'POST',
			url: this.basePath + '/api/sysFile/delete',
			headers,
			data: { id },
			responseType: 'json',
		};

		return this.axios.request<void>(requestConfig);
	}

	/**
	 * Get file details by ID
	 */
	async getFileDetails(id: number): Promise<AxiosResponse<AdminResultSysFile>> {
		const headers = await this.getHeaders('application/json');

		const requestConfig: AxiosRequestConfig = {
			method: 'GET',
			url: this.basePath + '/api/sysFile/file',
			headers,
			params: { id },
			responseType: 'json',
		};

		return this.axios.request<AdminResultSysFile>(requestConfig);
	}

	/**
	 * Update file metadata
	 */
	async updateFile(file: SysFile): Promise<AxiosResponse<void>> {
		const headers = await this.getHeaders('application/json');

		const requestConfig: AxiosRequestConfig = {
			method: 'POST',
			url: this.basePath + '/api/sysFile/update',
			headers,
			data: file,
			responseType: 'json',
		};

		return this.axios.request<void>(requestConfig);
	}

	/**
	 * Get files by relation
	 */
	async getRelationFiles(params: { relationName?: string; relationId?: number; category?: string; belongId?: number }): Promise<AxiosResponse<AdminResultListSysFile>> {
		const headers = await this.getHeaders('application/json');

		const requestConfig: AxiosRequestConfig = {
			method: 'GET',
			url: this.basePath + '/api/sysFile/relationFiles',
			headers,
			params,
			responseType: 'json',
		};

		return this.axios.request<AdminResultListSysFile>(requestConfig);
	}

	/**
	 * Preview file by ID
	 */
	async previewFile(id: number): Promise<AxiosResponse<AdminResultIActionResult>> {
		const headers = await this.getHeaders('application/json');

		const requestConfig: AxiosRequestConfig = {
			method: 'GET',
			url: this.basePath + `/api/sysFile/preview/${id}`,
			headers,
			responseType: 'blob',
		};

		return this.axios.request<AdminResultIActionResult>(requestConfig);
	}

	/**
	 * Get authorization headers
	 */
	private async getHeaders(contentType: string): Promise<Record<string, string>> {
		const headers: Record<string, string> = {
			'Content-Type': contentType,
		};

		if (this.configuration?.accessToken) {
			const token = typeof this.configuration.accessToken === 'function' ? await this.configuration.accessToken() : await this.configuration.accessToken;
			headers['Authorization'] = `Bearer ${token}`;
		}

		return headers;
	}
}
